package com.katze.boot.file.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.katze.boot.file.entity.*;
import com.katze.boot.file.entity.FileSystemConstant.Repository;
import com.katze.boot.file.service.FileDatabaseService;
import com.katze.boot.file.service.FileRepositoryService;
import com.katze.boot.file.service.FileService;
import com.katze.boot.file.service.FolderService;
import com.katze.boot.plugins.shiro.annotations.RestControllerMapping;
import com.katze.boot.plugins.shiro.annotations.RestRequestMapping;
import com.katze.common.Message;
import com.katze.common.Pagination;
import com.katze.common.controller.BaseController;
import com.katze.common.env.AppEnvironment;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMethod;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 文件系统
 * @描述： 整个系统上传的文件都由改文件系统控制
 * @作  者：2023-12-07
 * @日  期：2022-11-17
 */
@RestControllerMapping("/fileSystem")
public class FileSystemController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(FileSystemController.class);

    @Autowired
    private FileRepositoryService repositoryService;

    @Autowired
    private FileDatabaseService fileDatabaseService;

    @Autowired
    private FolderService folderService;

    @Autowired
    private FileService fileService;

    @RestRequestMapping(value = "/repository", permits = "fileRepository:view", skip = true)
    public Message getFileRepository() {
        return Message.ok().data(repositoryService.getById(Repository.DEFAULT_REPOSITORY_ID));
    }

    @RestRequestMapping(value = "/repository", permits = "fileRepository:edit", method = RequestMethod.POST, desc = "创建或更新文件仓信息")
    public Message saveOrUpdate(FileRepositoryEntity repository) {
        File tempDir;
        if (StringUtils.isNotBlank(repository.getTempPath())) {
            tempDir = new File(repository.getTempPath());
        } else {
            tempDir = new File(AppEnvironment.TEMP_DIR.getValue());
        }
        if (!tempDir.exists() && !tempDir.mkdirs()) {
            return Message.error("缓存路径初始化失败,请联系管理手动创建");
        }
        Message message = Message.ok(StringUtils.isBlank(repository.getId())? "创建成功":"修改成功");
        repositoryService.saveOrUpdate(repository);
        return message;
    }

    @RestRequestMapping(value = "/fileDatabase", permits = "fileRepository:view", skip = true)
    public Message fileDatabases(Pagination pagination, FileDatabaseEntity fileDatabase){
        return toDataTable(fileDatabaseService.findFileDatabases(pagination, fileDatabase));
    }

    @RestRequestMapping(value = "/fileDatabase", permits = {"fileDatabase:add", "fileDatabase:update"}, method = {RequestMethod.POST, RequestMethod.PUT}, desc = "创建或更新文件库信息")
    public Message editFileDatabase(FileDatabaseEntity fileDatabase){
        if (StringUtils.isBlank(fileDatabase.getId())) {
            fileDatabase.setCreateTime(new Date());
            if (fileDatabaseService.save(fileDatabase)) {
                try {
                    folderService.create(fileDatabase, fileDatabaseService::updateCurrentFolderId);
                    return Message.ok("创建成功");
                } catch (IOException e) {
                    log.error("{}下创建存储目录失败", fileDatabase.getPath(), e);
                    return Message.error("实体存储目录创建失败");
                }
            } else {
                return Message.error("存储路径已存在");
            }
        } else {
            fileDatabaseService.updateById(fileDatabase);
            return Message.ok("修改成功");
        }
    }

    @RestRequestMapping(value = "/files", permits = "fileRepository:view", skip = true)
    public Message files(Pagination pagination, FileDatabaseEntity fileDatabase){
        Object data = null;
        if (StringUtils.isNotBlank(fileDatabase.getCurrentFolderId()) && StringUtils.isNotBlank(fileDatabase.getId())) {
            FileEntity entity = new FileEntity();
            entity.setName(fileDatabase.getName());
            entity.setFileDatabaseExtendId(fileDatabase.getCurrentFolderId());
            entity.setFileDatabaseId(fileDatabase.getId());
            data = fileService.findFiles(pagination, entity);
        } else if (StringUtils.isNotBlank(fileDatabase.getId())) {
            FolderEntity entity = new FolderEntity();
            entity.setName(fileDatabase.getName());
            entity.setFileDatabaseId(fileDatabase.getId());
            data = folderService.findFolders(pagination, entity);
        }
        Map<String, Object> items = new HashMap<>();
        List<FileSystemResource> rows = new LinkedList<>();
        if (data instanceof IPage){
            rows = ((IPage<?>) data).getRecords().stream().map(FileSystemResource::new).collect(Collectors.toList());
            items.put("total", ((IPage<?>) data).getTotal());
        } else if (data instanceof List) {
            rows = ((List<?>) data).stream().map(FileSystemResource::new).collect(Collectors.toList());
            items.put("total", ((List<?>) data).size());
        }
        items.put("rows", rows);
        return Message.ok().data(items);
    }

    @RestRequestMapping(value = "/fileResources", permits = "fileRepository:view", skip = true)
    public Message files(Pagination pagination, FileEntity file) {
        Object files = fileService.findFiles(pagination, file);
        return toDataTable(files);
    }

    @RestRequestMapping(value = "/{type}", permits = "fileDatabase:delete", method = RequestMethod.DELETE, desc = "fileDatabase: 删除文件库; file:删除文件; folder:删除目录及其子文件")
    public Message delete(@PathVariable("type") String type, String id) {
        if (StringUtils.isBlank(id)) {
            return Message.error("找不到删除对象");
        } else {
            switch (type) {
                case "folder":
                    FileDatabaseEntity fileDatabase = fileDatabaseService.getCurrentFileDatabase();
                    if (id.equals(fileDatabase.getCurrentFolderId())) {
                        return Message.error("当前目录正在使用");
                    } else {
                        folderService.delete(id, false);
                        break;
                    }
                case "file":
                    fileService.delete(id.split(","));
                    break;
                case "fileDatabase":
                    FileRepositoryEntity fileRepository = repositoryService.getDefaultFileRepository();
                    if (id.equals(fileRepository.getDefaultFileDatabaseId())) {
                        return Message.error("当前文件库正在使用");
                    } else {
                        folderService.delete(id, true);
                        fileDatabaseService.removeById(id);
                        break;
                    }
                default:
                    return Message.error("删除类型不匹配");
            }
            return Message.ok("删除成功");
        }
    }
}
